﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using SGD;
using System.Diagnostics;


namespace WorldEditor
{
    public partial class Form1 : Form
    {
        public enum COLLISION_TYPE { NONE, SOLID, WATER, EVENT };
        public enum OBJECT_TYPE { NONE, ENEMYSPAWN, SAVEPOINT, WEAPON, UPGRADE, MAXHEALTHUP, LINEAR, WALL };
       
        public struct Tile
        {
            public int tileIndex;
            public COLLISION_TYPE collisionType;
            public string collisionEvent;
            public string objectName;
            public OBJECT_TYPE objectType;
            public Pen collisionPen;
            public bool hasCollision;
            public bool hasObject;
            public bool hasEvent;
            public int pairedTileX;
            public int pairedTileY;
        }

        public struct Layer
        {
            public Tile[,] map;
            public string layerName;
            public bool visible;
        }

        private ManagedDirect3D d3d = ManagedDirect3D.Instance;
        private ManagedTextureManager tm = ManagedTextureManager.Instance;
        public bool Looping = true;

        public int imageID;
        public string filepath;
        public string filename;
        public List<Layer> layerList = new List<Layer>(3);
        public Layer currentLayer;

        public bool[,] tileSetGrid = new bool[0, 0];
        public int tileSetWidth;
        public int tileSetHeight;
        public bool showTiles;
        public bool showObjects;
        public bool showCollision;

        public int mapWidth;
        public int mapHeight;

        public string objectName;
        public OBJECT_TYPE objectType;

        public int selectedTile = -1;
        public bool tileSelected = false;

        public Point updatePointTS;
        public bool tsNeedsUpdate;
        public Point updatePointMap;
        public bool mapNeedsUpdate;
        public bool leftClick;

        public int indexToPairX;
        public int indexToPairY;
       
        new public void Update()
        {
            if(mapNeedsUpdate)
            {
                //TILES
                if (tabControl1.SelectedTab == tabControl1.TabPages[0])
                {
                    if (leftClick)
                    {
                        if (tileSelected)
                        {
                            for (int r = 0; r < mapHeight; ++r)
                            {
                                for (int c = 0; c < mapWidth; ++c)
                                {
                                    if (currentLayer.map[c, r].tileIndex != selectedTile)
                                    {
                                        if (updatePointMap.X + hMapScroll.Value >= (c * (int)tileWidthUpDown.Value) &&
                                            updatePointMap.X + hMapScroll.Value <= (c * (int)tileWidthUpDown.Value) + (int)tileWidthUpDown.Value &&
                                            updatePointMap.Y + vMapScroll.Value >= (r * (int)tileHeightUpDown.Value) &&
                                            updatePointMap.Y + vMapScroll.Value <= (r * (int)tileHeightUpDown.Value) + (int)tileHeightUpDown.Value)
                                        {
                                            currentLayer.map[c, r].tileIndex = selectedTile;
                                            mapNeedsUpdate = false;
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (tileSelected)
                        {
                            for (int r = 0; r < mapHeight; ++r)
                            {
                                for (int c = 0; c < mapWidth; ++c)
                                {
                                    if (updatePointMap.X + hMapScroll.Value >= (c * (int)tileWidthUpDown.Value) &&
                                        updatePointMap.X + hMapScroll.Value <= (c * (int)tileWidthUpDown.Value) + (int)tileWidthUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value >= (r * (int)tileHeightUpDown.Value) &&
                                        updatePointMap.Y + vMapScroll.Value <= (r * (int)tileHeightUpDown.Value) + (int)tileHeightUpDown.Value)
                                    {
                                        currentLayer.map[c, r].tileIndex = -1;
                                        mapNeedsUpdate = false;
                                        updatePointMap.X = 0;
                                        updatePointMap.Y = 0;
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }
                //COLLISION
                else if (tabControl1.SelectedTab == tabControl1.TabPages[1])
                {
                    if (solidCollisionRadio.Checked)
                    {
                        if (leftClick) 
                        {
                            for (int r = 0; r < mapHeight; ++r)
                            {
                                for (int c = 0; c < mapWidth; ++c)
                                {
                                    if (updatePointMap.X + hMapScroll.Value >= c * (int)tileWidthUpDown.Value &&
                                        updatePointMap.X + hMapScroll.Value <= c * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value >= r * (int)tileHeightUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value <= r * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value)
                                    {
                                        currentLayer.map[c, r].collisionType = COLLISION_TYPE.SOLID;
                                        currentLayer.map[c, r].collisionEvent = null;
                                        currentLayer.map[c, r].hasCollision = true;
                                        currentLayer.map[c, r].hasEvent = false;
                                        updatePointMap.X = 0;
                                        updatePointMap.Y = 0;
                                        mapNeedsUpdate = false;
                                        return;
                                    }
                                }
                            }
                        }
                        else
                        {
                            for (int r = 0; r < mapHeight; ++r)
                            {
                                for (int c = 0; c < mapWidth; ++c)
                                {
                                    if (updatePointMap.X + hMapScroll.Value >= c * (int)tileWidthUpDown.Value &&
                                        updatePointMap.X + hMapScroll.Value <= c * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value >= r * (int)tileHeightUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value <= r * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value)
                                    {
                                        currentLayer.map[c, r].collisionType = COLLISION_TYPE.NONE;
                                        currentLayer.map[c, r].collisionEvent = null;
                                        currentLayer.map[c, r].hasCollision = false;
                                        currentLayer.map[c, r].hasEvent = false;
                                        updatePointMap.X = 0;
                                        updatePointMap.Y = 0;
                                        mapNeedsUpdate = false;
                                        return;
                                    }
                                }
                            }
                        }
                    }
                    else if (waterCollisionRadio.Checked)
                    {
                        if (leftClick)
                        {
                            for (int r = 0; r < mapHeight; ++r)
                            {
                                for (int c = 0; c < mapWidth; ++c)
                                {
                                    if (updatePointMap.X + hMapScroll.Value >= c * (int)tileWidthUpDown.Value &&
                                        updatePointMap.X + hMapScroll.Value <= c * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value >= r * (int)tileHeightUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value <= r * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value)
                                    {
                                        currentLayer.map[c, r].collisionType = COLLISION_TYPE.WATER;
                                        currentLayer.map[c, r].collisionEvent = null;
                                        currentLayer.map[c, r].hasCollision = true;
                                        currentLayer.map[c, r].hasEvent = false;
                                        updatePointMap.X = 0;
                                        updatePointMap.Y = 0;
                                        mapNeedsUpdate = false;
                                        return;
                                    }
                                }
                            }
                        }
                        else
                        {
                            for (int r = 0; r < mapHeight; ++r)
                            {
                                for (int c = 0; c < mapWidth; ++c)
                                {
                                    if (updatePointMap.X + hMapScroll.Value >= c * (int)tileWidthUpDown.Value &&
                                        updatePointMap.X + hMapScroll.Value <= c * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value >= r * (int)tileHeightUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value <= r * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value)
                                    {
                                        currentLayer.map[c, r].collisionType = COLLISION_TYPE.NONE;
                                        currentLayer.map[c, r].collisionEvent = null;
                                        currentLayer.map[c, r].hasCollision = false;
                                        currentLayer.map[c, r].hasEvent = false;
                                        updatePointMap.X = 0;
                                        updatePointMap.Y = 0;
                                        mapNeedsUpdate = false;
                                        return;
                                    }
                                }
                            }
                        }
                    }
                    else if (eventCollisionRadio.Checked)
                    {
                        if (leftClick)
                        {
                            for (int r = 0; r < mapHeight; ++r)
                            {
                                for (int c = 0; c < mapWidth; ++c)
                                {
                                    if (updatePointMap.X + hMapScroll.Value >= c * (int)tileWidthUpDown.Value &&
                                        updatePointMap.X + hMapScroll.Value <= c * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value >= r * (int)tileHeightUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value <= r * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value)
                                    {
                                        textBox1.SelectAll();

                                        string text = textBox1.SelectedText;

                                        if (text.Length == 0)
                                        {
                                            MessageBox.Show("Please enter an event string to attach to the tile.");
                                            updatePointMap.X = 0;
                                            updatePointMap.Y = 0;
                                            mapNeedsUpdate = false;
                                            return;
                                        }
                                        else
                                        {
                                            currentLayer.map[c, r].collisionType = COLLISION_TYPE.EVENT;
                                            currentLayer.map[c, r].collisionEvent = text;
                                            currentLayer.map[c, r].hasCollision = true;
                                            currentLayer.map[c, r].hasEvent = true;
                                            updatePointMap.X = 0;
                                            updatePointMap.Y = 0;
                                            mapNeedsUpdate = false;
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            for (int r = 0; r < mapHeight; ++r)
                            {
                                for (int c = 0; c < mapWidth; ++c)
                                {
                                    if (updatePointMap.X + hMapScroll.Value >= c * (int)tileWidthUpDown.Value &&
                                        updatePointMap.X + hMapScroll.Value <= c * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value >= r * (int)tileHeightUpDown.Value &&
                                        updatePointMap.Y + vMapScroll.Value <= r * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value)
                                    {
                                        currentLayer.map[c, r].collisionType = COLLISION_TYPE.NONE;
                                        currentLayer.map[c, r].collisionEvent = null;
                                        currentLayer.map[c, r].hasCollision = false;
                                        currentLayer.map[c, r].hasEvent = false;
                                        updatePointMap.X = 0;
                                        updatePointMap.Y = 0;
                                        mapNeedsUpdate = false;
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }
                //GAME OBJECTS
                else if (tabControl1.SelectedTab == tabControl1.TabPages[2])
                {
                    if (leftClick)
                    {
                        
                        for (int r = 0; r < mapHeight; ++r)
                        {
                            for (int c = 0; c < mapWidth; ++c)
                            {
                                if (updatePointMap.X + hMapScroll.Value >= c * (int)tileWidthUpDown.Value &&
                                    updatePointMap.X + hMapScroll.Value <= c * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value &&
                                    updatePointMap.Y + vMapScroll.Value >= r * (int)tileHeightUpDown.Value &&
                                    updatePointMap.Y + vMapScroll.Value <= r * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value)
                                {
                                    if (linearityRadio.Checked)
                                    {
                                        if (indexToPairX == -1)
                                        {
                                            indexToPairX = c;
                                            indexToPairY = r;

                                            updatePointMap.X = 0;
                                            updatePointMap.Y = 0;
                                            mapNeedsUpdate = false;
                                            return;
                                        }
                                        else
                                        {
                                            if (c == indexToPairX && r == indexToPairY)
                                            {
                                                indexToPairX = -1;
                                                indexToPairY = -1;

                                                updatePointMap.X = 0;
                                                updatePointMap.Y = 0;
                                                mapNeedsUpdate = false;
                                                return;
                                            }
                                            else
                                            {
                                                currentLayer.map[c, r].pairedTileX = indexToPairX;
                                                currentLayer.map[c, r].pairedTileY = indexToPairY;
                                                currentLayer.map[c, r].objectName = objectName;
                                                currentLayer.map[c, r].objectType = objectType;
                                                currentLayer.map[c, r].hasObject = true;

                                                currentLayer.map[indexToPairX, indexToPairY].pairedTileX = c;
                                                currentLayer.map[indexToPairX, indexToPairY].pairedTileY = r;
                                                currentLayer.map[indexToPairX, indexToPairY].objectName = objectName;
                                                currentLayer.map[indexToPairX, indexToPairY].objectType = objectType;
                                                currentLayer.map[indexToPairX, indexToPairY].hasObject = true;

                                                indexToPairX = -1;
                                                indexToPairY = -1;

                                                updatePointMap.X = 0;
                                                updatePointMap.Y = 0;
                                                mapNeedsUpdate = false;
                                                return;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        currentLayer.map[c, r].objectName = objectName;
                                        currentLayer.map[c, r].objectType = objectType;
                                        currentLayer.map[c, r].hasObject = true;
                                        updatePointMap.X = 0;
                                        updatePointMap.Y = 0;
                                        mapNeedsUpdate = false;
                                        return;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int r = 0; r < mapHeight; ++r)
                        {
                            for (int c = 0; c < mapWidth; ++c)
                            {
                                if (updatePointMap.X + hMapScroll.Value >= c * (int)tileWidthUpDown.Value &&
                                    updatePointMap.X + hMapScroll.Value <= c * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value &&
                                    updatePointMap.Y + vMapScroll.Value >= r * (int)tileHeightUpDown.Value &&
                                    updatePointMap.Y + vMapScroll.Value <= r * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value)
                                {
                                    currentLayer.map[c, r].objectName = null;
                                    currentLayer.map[c, r].objectType = OBJECT_TYPE.NONE;
                                    currentLayer.map[c, r].hasObject = false;

                                    if (currentLayer.map[c, r].pairedTileX != -1)
                                    {
                                        currentLayer.map[currentLayer.map[c, r].pairedTileX, currentLayer.map[c, r].pairedTileY].objectName = null;
                                        currentLayer.map[currentLayer.map[c, r].pairedTileX, currentLayer.map[c, r].pairedTileY].objectType = OBJECT_TYPE.NONE;
                                        currentLayer.map[currentLayer.map[c, r].pairedTileX, currentLayer.map[c, r].pairedTileY].hasObject = false;
                                        currentLayer.map[currentLayer.map[c, r].pairedTileX, currentLayer.map[c, r].pairedTileY].pairedTileX = -1;
                                        currentLayer.map[currentLayer.map[c, r].pairedTileX, currentLayer.map[c, r].pairedTileY].pairedTileY = -1;
                                        currentLayer.map[c, r].pairedTileX = -1;
                                        currentLayer.map[c, r].pairedTileY = -1;
                                    }

                                    updatePointMap.X = 0;
                                    updatePointMap.Y = 0;
                                    mapNeedsUpdate = false;
                                    return;
                                }
                            }
                        }
                    }
                }

                updatePointMap.X = 0;
                updatePointMap.Y = 0;
                mapNeedsUpdate = false;
            }
            //TILESET UPDATE
            if (tsNeedsUpdate)
            {
                int check = 0;
                if (updatePointTS.X + hTileScroll.Value >= 0 &&
                    updatePointTS.X + hTileScroll.Value <= (tileSetWidth * (int)tileWidthUpDown.Value) &&
                    updatePointTS.Y + vTileScroll.Value >= 0 &&
                    updatePointTS.Y + vTileScroll.Value <= (tileSetHeight * (int)tileHeightUpDown.Value))
                {
                    for (int r = 0; r < tileSetHeight; ++r)
                    {
                        for (int c = 0; c < tileSetWidth; ++c)
                        {
                            if (updatePointTS.X + hTileScroll.Value >= c * tileWidthUpDown.Value &&
                                updatePointTS.X + hTileScroll.Value <= c * tileWidthUpDown.Value + tileWidthUpDown.Value &&
                                updatePointTS.Y + vTileScroll.Value >= r * tileHeightUpDown.Value &&
                                updatePointTS.Y + vTileScroll.Value <= r * tileHeightUpDown.Value + tileHeightUpDown.Value)
                            {
                                for (int i = 0; i < tileSetWidth; ++i)
                                {
                                    for (int j = 0; j < tileSetHeight; ++j)
                                    {
                                        tileSetGrid[i, j] = false;
                                    }
                                }
                                tileSetGrid[c, r] = true;
                            }


                            if (updatePointTS.X + hTileScroll.Value >= c * tileWidthUpDown.Value &&
                              updatePointTS.X + hTileScroll.Value <= c * tileWidthUpDown.Value + tileWidthUpDown.Value &&
                              updatePointTS.Y + vTileScroll.Value >= r * tileHeightUpDown.Value &&
                              updatePointTS.Y + vTileScroll.Value <= r * tileHeightUpDown.Value + tileHeightUpDown.Value)
                            {
                                selectedTile = check;
                                tileSelected = true;
                                tsNeedsUpdate = false;
                                updatePointTS.X = 0;
                                updatePointTS.Y = 0;
                                return;
                            }
                            ++check;
                        }
                    }
                }
                tileSelected = false;
                tsNeedsUpdate = false;
                updatePointTS.X = 0;
                updatePointTS.Y = 0;
            }
        }

        public void Render()
        {
            //TILESET RENDERING
            d3d.ChangeDisplayParam(pictureBox2, false);
            d3d.Clear(0,0,0);
            d3d.DeviceBegin();
            d3d.SpriteBegin();

            Rectangle dRect = new Rectangle(0, 0, tm.GetTextureWidth(imageID), tm.GetTextureHeight(imageID));
            tm.Draw(imageID, 0 - hTileScroll.Value, 0 - vTileScroll.Value, 1.0f, 1.0f, Rectangle.Empty, 0, 0, 0, 0);
            d3d.SpriteEnd();

            for (int r = 0; r < tileSetWidth; ++r)
            {
                for (int c = 0; c < tileSetHeight; ++c)
                {
                    if (tileSetGrid[r, c] == true)
                    {
                        d3d.LineBegin();
                        //LEFT LINE OF SELECTION RECT
                        d3d.DrawLine((r * (int)tileWidthUpDown.Value) - hTileScroll.Value, (c * (int)tileHeightUpDown.Value) - vTileScroll.Value,
                            (r * (int)tileWidthUpDown.Value) - hTileScroll.Value, (c * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vTileScroll.Value, 255, 0, 0);
                        //RIGHT LINE OF SELECTION RECT
                        d3d.DrawLine((r * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hTileScroll.Value, (c * (int)tileHeightUpDown.Value) - vTileScroll.Value,
                            (r * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hTileScroll.Value, (c * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vTileScroll.Value, 255, 0, 0);
                        //TOP LINE OF SELECTION RECT
                        d3d.DrawLine((r * (int)tileWidthUpDown.Value) - hTileScroll.Value, (c * (int)tileHeightUpDown.Value) - vTileScroll.Value,
                            (r * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hTileScroll.Value, (c * (int)tileHeightUpDown.Value) - vTileScroll.Value, 255, 0, 0);
                        //BOTTOM LINE OF SELECTION RECT
                        d3d.DrawLine((r * (int)tileWidthUpDown.Value) - hTileScroll.Value, (c * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vTileScroll.Value,
                            (r * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hTileScroll.Value, (c * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vTileScroll.Value, 255, 0, 0);
                        d3d.LineEnd();
                    }
                }
            }
            d3d.DeviceEnd();
            d3d.Present();


            //MAP RENDERING
            d3d.ChangeDisplayParam(pictureBox1, false);
            d3d.Clear(200, 200, 200);
            d3d.DeviceBegin();

            d3d.LineBegin();
            for (int r = 0; r < mapHeight + 1; ++r)
            {
                d3d.DrawLine(0 - hMapScroll.Value, (r * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                    ((int)tileWidthUpDown.Value * mapWidth) - hMapScroll.Value, (r * (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 0, 0);
                
            }
            for (int c = 0; c < mapWidth + 1; ++c)
            {
                d3d.DrawLine((c * (int)tileWidthUpDown.Value) - hMapScroll.Value, 0 - vMapScroll.Value,
                    (c * (int)tileWidthUpDown.Value) - hMapScroll.Value, ((int)tileHeightUpDown.Value * mapHeight) - vMapScroll.Value, 0, 0, 0);
            }
            d3d.LineEnd();

            d3d.SpriteBegin();
            for (int layer = 0; layer < 3; ++layer)
            {
                if (layerList[layer].visible)
                {
                    for (int i = 0; i < mapWidth; ++i)
                    {
                        for (int j = 0; j < mapHeight; ++j)
                        {
                            if (showTiles)
                            {
                                if (layerList[layer].map[i, j].tileIndex != -1)
                                {
                                    int drawTile = layerList[layer].map[i, j].tileIndex;
                                    int moveDown = 0;

                                    while (drawTile > (tileSetWidth - 1))
                                    {
                                        drawTile -= tileSetWidth;
                                        ++moveDown;
                                    }

                                    Rectangle rect = new Rectangle(drawTile * (int)tileWidthUpDown.Value,
                                                            moveDown * (int)tileHeightUpDown.Value,
                                                            (int)tileWidthUpDown.Value, (int)tileHeightUpDown.Value);

                                    tm.Draw(imageID, (i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value, 1.0f, 1.0f, rect, 0, 0, 0.0f, 0);
                                }
                            }
                        }
                    }
                }
            }
            d3d.SpriteEnd();

            d3d.LineBegin();
            for (int layer = 0; layer < 3; ++layer)
            {
                if (layerList[layer].visible)
                {
                    for (int i = 0; i < mapWidth; ++i)
                    {
                        for (int j = 0; j < mapHeight; ++j)
                        {
                            if (showCollision)
                            {
                                if (layerList[layer].map[i, j].collisionType != COLLISION_TYPE.NONE)
                                {
                                    switch ((int)layerList[layer].map[i, j].collisionType)
                                    {
                                        case (int)COLLISION_TYPE.SOLID:
                                            {
                                                //LEFT LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 255, 0, 0);
                                                //RIGHT LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 255, 0, 0);
                                                //TOP LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value, 255, 0, 0);
                                                //BOTTOM LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 255, 0, 0);                                          
                                            }
                                            break;
                                        case (int)COLLISION_TYPE.WATER:
                                            {
                                                //LEFT LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 0, 255);
                                                //RIGHT LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 0, 255);
                                                //TOP LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 0, 255);
                                                //BOTTOM LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 0, 255);
                                            }
                                            break;
                                        case (int)COLLISION_TYPE.EVENT:
                                            {
                                                //LEFT LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 255, 0);
                                                //RIGHT LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 255, 0);
                                                //TOP LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 255, 0);
                                                //BOTTOM LINE
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 255, 0);
                                            }
                                            break;
                                    }
                                }
                            }
                            if (showObjects)
                            {
                                if (layerList[layer].map[i, j].objectType != OBJECT_TYPE.NONE)
                                {
                                    switch ((int)layerList[layer].map[i, j].objectType)
                                    {
                                        case (int)OBJECT_TYPE.ENEMYSPAWN:
                                            {
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 255, 0, 0);
                                            }
                                            break;
                                        case (int)OBJECT_TYPE.SAVEPOINT:
                                            {
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 255, 255, 0);
                                            }
                                            break;
                                        case (int)OBJECT_TYPE.WEAPON:
                                            {
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 0, 255);
                                            }
                                            break;
                                        case (int)OBJECT_TYPE.UPGRADE:
                                            {
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 255, 128, 0);
                                            }
                                            break;
                                        case (int)OBJECT_TYPE.MAXHEALTHUP:
                                            {
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 255, 0);
                                            }
                                            break;
                                        case (int)OBJECT_TYPE.LINEAR:
                                            {
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 128, 0, 255);
                                            }
                                            break;
                                        case (int)OBJECT_TYPE.WALL:
                                            {
                                                d3d.DrawLine((i * (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value) - vMapScroll.Value,
                                                    (i * (int)tileWidthUpDown.Value + (int)tileWidthUpDown.Value) - hMapScroll.Value, (j * (int)tileHeightUpDown.Value + (int)tileHeightUpDown.Value) - vMapScroll.Value, 0, 0, 0);
                                            }
                                            break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            d3d.LineEnd();

            d3d.DeviceEnd();
            d3d.Present();
        }


        //FORM CONSTRUCTOR
        public Form1()
        {
            InitializeComponent();

            d3d.InitManagedDirect3D(pictureBox2, false);
            tm.InitManagedTextureManager(d3d.Device, d3d.Sprite);

            tsNeedsUpdate = false;
            updatePointTS.X = 0;
            updatePointTS.Y = 0;
            mapNeedsUpdate = false;
            updatePointMap.X = 0;
            updatePointMap.Y = 0;

            imageID = tm.LoadTexture(Environment.CurrentDirectory + "\\_default.jpg", Color.Black.ToArgb());
            filename = "_default.jpg";
            filepath = null;

            mapWidth = (int)mapWidthUpDown.Value;
            mapHeight = (int)mapHeightUpDown.Value;
            tileSetWidth = tm.GetTextureWidth(imageID) / (int)tileWidthUpDown.Value;
            tileSetHeight = tm.GetTextureHeight(imageID) / (int)tileHeightUpDown.Value;

            hMapScroll.Maximum = mapWidth * (int)tileWidthUpDown.Value;
            vMapScroll.Maximum = mapHeight * (int)tileHeightUpDown.Value;
            hTileScroll.Maximum = tm.GetTextureWidth(imageID);
            vTileScroll.Maximum = tm.GetTextureHeight(imageID);

            indexToPairX = -1;
            indexToPairY = -1;
            
            solidCollisionRadio.Select();
            enemySpawnRadio.Select();
            stickGuardRadio.Select();
            swordStickGuardRadio.Select();
            tilesCheckBox.Checked = true;
            collisionCheckBox.Checked = true;
            objectsCheckBox.Checked = true;
            showTiles = true;
            showObjects = true;
            showCollision = true;

            for (int i = 0; i < 3; ++i)
            {
                Layer tempLayer = new Layer();
                switch (i)
                {
                    case 0:
                        tempLayer.layerName = "Main Layer";
                        break;
                    case 1:
                        tempLayer.layerName = "Hidden Layer";
                        break;
                    case 2:
                        tempLayer.layerName = "Inverse Layer";
                        break;
                }
                tempLayer.map = new Tile[mapWidth, mapHeight];
                for (int j = 0; j < mapWidth; ++j)
                    for (int k = 0; k < mapHeight; ++k)
                    {
                        tempLayer.map[j, k].tileIndex = -1;
                        tempLayer.map[j, k].collisionEvent = null;
                        tempLayer.map[j, k].collisionType = COLLISION_TYPE.NONE;
                        tempLayer.map[j, k].objectName = null;
                        tempLayer.map[j, k].objectType = OBJECT_TYPE.NONE;
                        tempLayer.map[j, k].hasCollision = false;
                        tempLayer.map[j, k].hasObject = false;
                        tempLayer.map[j, k].hasEvent = false;
                        tempLayer.map[j, k].pairedTileX = -1;
                        tempLayer.map[j, k].pairedTileY = -1;

                    }
                tempLayer.visible = true;

                layerList.Insert(i, tempLayer);
                listBox1.Items.Add(layerList[i].layerName);
            }
            listBox1.SelectedItem = listBox1.Items[0];
            currentLayer = layerList[0];


            tileSetGrid = new bool[tileSetWidth, tileSetHeight];
            for (int i = 0; i < tileSetWidth; ++i)
            {
                for (int j = 0; j < tileSetHeight; ++j)
                {
                    tileSetGrid[i, j] = false;
                }
            }
        }

        //MAP PANEL MOUSE INFORMATION
        //MouseClick
        //MouseMove
        private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
        {
            mapNeedsUpdate = true;
            updatePointMap.X = e.X;
            updatePointMap.Y = e.Y;
            if (e.Button == MouseButtons.Left)
                leftClick = true;
            else
                leftClick = false;
        }
        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (MouseButtons.Left == e.Button)
            {
                mapNeedsUpdate = true;
                updatePointMap.X = e.X;
                updatePointMap.Y = e.Y;
                leftClick = true;
            }
            else if (MouseButtons.Right == e.Button)
            {
                mapNeedsUpdate = true;
                updatePointMap.X = e.X;
                updatePointMap.Y = e.Y;
                leftClick = false;
            }

        }
               
        //TILESET PANEL MOUSE INFORMATION
        //MouseClick
        private void pictureBox2_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                tsNeedsUpdate = true;
                updatePointTS.X = e.X;
                updatePointTS.Y = e.Y;
            }
        }
        
        //RADIO BUTTONS
        //Solid Collision
        //Water Collision
        //Event Collision
        private void solidCollisionRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (textBox1.Visible)
            {
                textBox1.Hide();
                label8.Hide();
            }
        }
        private void waterCollisionRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (textBox1.Visible)
            {
                textBox1.Hide();
                label8.Hide();
            }
        }
        private void eventCollisionRadio_CheckedChanged(object sender, EventArgs e)
        {
            textBox1.Show();
            label8.Show();
        }

        //EnemySpawn        
        //StickGuard        
        //SwordStickGuard
        //SpearStickGuard
        //FistStickGuard
        //BabyDargon
        //StickDog
        //SavePoint
        //Weapon        
        //Sword
        //Spear
        //MaxHealth
        private void enemySpawnRadio_CheckedChanged(object sender, EventArgs e)
        {
            weaponTypeGroup.Hide();
            upgradeGroup.Hide();
            enemyTypeGroup.Show();
            guardTypeGroup.Show();
            stickGuardRadio.Select();
            swordStickGuardRadio.Select();
            objectName = "swordStickGuard";
            objectType = OBJECT_TYPE.ENEMYSPAWN;
        }
        private void stickGuardRadio_CheckedChanged(object sender, EventArgs e)
        {
            guardTypeGroup.Show();
            swordStickGuardRadio.Select();
            objectName = "swordStickGuard";
            objectType = OBJECT_TYPE.ENEMYSPAWN;
        }
        private void swordStickGuardRadio_CheckedChanged(object sender, EventArgs e)
        {
            objectName = "swordStickGuard";
            objectType = OBJECT_TYPE.ENEMYSPAWN;
        }
        private void spearStickGuardRadio_CheckedChanged(object sender, EventArgs e)
        {
            objectName = "spearStickGuard";
            objectType = OBJECT_TYPE.ENEMYSPAWN;
        }
        private void fistStickGuardRadio_CheckedChanged(object sender, EventArgs e)
        {
            objectName = "fistStickGuard";
            objectType = OBJECT_TYPE.ENEMYSPAWN;
        }
        private void babyDargonRadio_CheckedChanged(object sender, EventArgs e)
        {
            guardTypeGroup.Hide();
            objectName = "babyDargon";
            objectType = OBJECT_TYPE.ENEMYSPAWN;
        }
        private void stickDogRadio_CheckedChanged(object sender, EventArgs e)
        {
            guardTypeGroup.Hide();
            objectName = "stickDog";
            objectType = OBJECT_TYPE.ENEMYSPAWN;
        }
        private void savePointRadio_CheckedChanged(object sender, EventArgs e)
        {
            enemyTypeGroup.Hide();
            weaponTypeGroup.Hide();
            upgradeGroup.Hide();
            guardTypeGroup.Hide();
            objectName = "savePoint";
            objectType = OBJECT_TYPE.SAVEPOINT;
        }
        private void weaponRadio_CheckedChanged(object sender, EventArgs e)
        {
            enemyTypeGroup.Hide();
            guardTypeGroup.Hide();
            upgradeGroup.Hide();
            weaponTypeGroup.Show();
            swordRadio.Select();
            objectType = OBJECT_TYPE.WEAPON;
        }
        private void swordRadio_CheckedChanged(object sender, EventArgs e)
        {
            objectName = "swordWeapon";
            objectType = OBJECT_TYPE.WEAPON;
        }
        private void SpearRadio_CheckedChanged(object sender, EventArgs e)
        {
            objectName = "spearWeapon";
            objectType = OBJECT_TYPE.WEAPON;
        }
        private void upgradeRadio_CheckedChanged(object sender, EventArgs e)
        {
            enemyTypeGroup.Hide();
            guardTypeGroup.Hide();
            weaponTypeGroup.Hide();
            upgradeGroup.Show();
            fistUpgradeRadio.Select();
            objectName = "fistUpgrade";
            objectType = OBJECT_TYPE.UPGRADE;
        }
        private void fistUpgradeRadio_CheckedChanged(object sender, EventArgs e)
        {
            objectName = "fistUpgrade";
            objectType = OBJECT_TYPE.UPGRADE;
        }

        private void swordUpgradeRadio_CheckedChanged(object sender, EventArgs e)
        {
            objectName = "swordUpgrade";
            objectType = OBJECT_TYPE.UPGRADE;
        }

        private void spearUpgradeRadio_CheckedChanged(object sender, EventArgs e)
        {
            objectName = "spearUpgrade";
            objectType = OBJECT_TYPE.UPGRADE;
        }
        private void maxHealthUpRadio_CheckedChanged(object sender, EventArgs e)
        {
            enemyTypeGroup.Hide();
            weaponTypeGroup.Hide();
            guardTypeGroup.Hide();
            upgradeGroup.Hide();
            objectName = "maxHealthUp";
            objectType = OBJECT_TYPE.MAXHEALTHUP;
        }
        private void linearityRadio_CheckedChanged(object sender, EventArgs e)
        {
            enemyTypeGroup.Hide();
            weaponTypeGroup.Hide();
            guardTypeGroup.Hide();
            upgradeGroup.Hide();
            objectName = "linearityCrack";
            objectType = OBJECT_TYPE.LINEAR;
        }
        private void breakableWallRadio_CheckedChanged(object sender, EventArgs e)
        {
            enemyTypeGroup.Hide();
            weaponTypeGroup.Hide();
            guardTypeGroup.Hide();
            upgradeGroup.Hide();
            objectName = "breakableWall";
            objectType = OBJECT_TYPE.WALL;
        }

        

        //CHECK BOXES
        //Show Tiles
        //Show Collision
        //Show Objects
        private void tilesCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            showTiles = !showTiles;
        }
        private void collisionCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            showCollision = !showCollision;
        }
        private void objectsCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            showObjects = !showObjects;
        }
        
        //NUMERIC UPDOWNS  
        //MapWidth
        //MapHeight
        //TileWidth
        //TileHeight
        private void mapWidthUpDown_ValueChanged(object sender, EventArgs e)
        {
            int oldMapWidth = mapWidth;
            mapWidth = (int)mapWidthUpDown.Value;
            hMapScroll.Maximum = mapWidth * (int)tileWidthUpDown.Value;

            for (int i = 0; i < 3; ++i)
            {
                if (currentLayer.layerName.ToString() == layerList[i].layerName.ToString())
                {
                    layerList.Remove(layerList[i]);
                    layerList.Insert(i, currentLayer);
                    currentLayer = layerList[i];
                    listBox1.SelectedItem = currentLayer.layerName.ToString();
                }
            }



            for (int layer = 0; layer < 3; ++layer)
            {
                Tile[,] tempArr = new Tile[mapWidth, mapHeight];
                currentLayer = layerList[layer];
                currentLayer.layerName = listBox1.Items[layer].ToString();
                for (int i = 0; i < mapWidth; ++i)
                {
                    for (int j = 0; j < mapHeight; ++j)
                    {
                        tempArr[i, j].tileIndex = -1;
                        tempArr[i, j].hasCollision = false;
                        tempArr[i, j].collisionType = COLLISION_TYPE.NONE;
                        tempArr[i, j].hasEvent = false;
                        tempArr[i, j].collisionEvent = null;
                        tempArr[i, j].hasObject = false;
                        tempArr[i, j].objectType = OBJECT_TYPE.NONE;
                        tempArr[i, j].objectName = null;
                        tempArr[i, j].pairedTileX = -1;
                        tempArr[i, j].pairedTileY = -1;
                    }
                }
                if (oldMapWidth < mapWidth)
                {
                    for (int i = 0; i < oldMapWidth; ++i)
                    {
                        for (int j = 0; j < mapHeight; ++j)
                        {
                            tempArr[i, j].tileIndex = currentLayer.map[i, j].tileIndex;
                            tempArr[i, j].hasCollision = currentLayer.map[i, j].hasCollision;
                            tempArr[i, j].collisionType = currentLayer.map[i, j].collisionType;
                            tempArr[i, j].hasEvent = currentLayer.map[i, j].hasEvent;
                            tempArr[i, j].collisionEvent = currentLayer.map[i, j].collisionEvent;
                            tempArr[i, j].hasObject = currentLayer.map[i, j].hasObject;
                            tempArr[i, j].objectType = currentLayer.map[i, j].objectType;
                            tempArr[i, j].objectName = currentLayer.map[i, j].objectName;
                            tempArr[i, j].pairedTileX = currentLayer.map[i, j].pairedTileX;
                            tempArr[i, j].pairedTileY = currentLayer.map[i, j].pairedTileY;

                        }
                    }
                }
                else
                {
                    for (int i = 0; i < mapWidth; ++i)
                    {
                        for (int j = 0; j < mapHeight; ++j)
                        {
                            tempArr[i, j].tileIndex = currentLayer.map[i, j].tileIndex;
                            tempArr[i, j].hasCollision = currentLayer.map[i, j].hasCollision;
                            tempArr[i, j].collisionType = currentLayer.map[i, j].collisionType;
                            tempArr[i, j].hasEvent = currentLayer.map[i, j].hasEvent;
                            tempArr[i, j].collisionEvent = currentLayer.map[i, j].collisionEvent;
                            tempArr[i, j].hasObject = currentLayer.map[i, j].hasObject;
                            tempArr[i, j].objectType = currentLayer.map[i, j].objectType;
                            tempArr[i, j].objectName = currentLayer.map[i, j].objectName;
                            tempArr[i, j].pairedTileX = currentLayer.map[i, j].pairedTileX;
                            tempArr[i, j].pairedTileY = currentLayer.map[i, j].pairedTileY;

                        }
                    }
                }
                currentLayer.map = tempArr;
                layerList.Remove(layerList[layer]);
                layerList.Insert(layer, currentLayer);
                currentLayer = layerList[layer];
            }
        }
        private void mapHeightUpDown_ValueChanged(object sender, EventArgs e)
        {
            int oldMapHeight = mapHeight;
            mapHeight = (int)mapHeightUpDown.Value;
            vMapScroll.Maximum = mapHeight * (int)tileHeightUpDown.Value;

            for (int i = 0; i < 3; ++i)
            {
                if (currentLayer.layerName.ToString() == layerList[i].layerName.ToString())
                {
                    layerList.Remove(layerList[i]);
                    layerList.Insert(i, currentLayer);
                    currentLayer = layerList[i];
                    listBox1.SelectedItem = currentLayer.layerName.ToString();
                }
            }



            for (int layer = 0; layer < 3; ++layer)
            {
                Tile[,] tempArr = new Tile[mapWidth, mapHeight];
                currentLayer = layerList[layer];
                currentLayer.layerName = listBox1.Items[layer].ToString();
                for (int i = 0; i < mapWidth; ++i)
                {
                    for (int j = 0; j < mapHeight; ++j)
                    {
                        tempArr[i, j].tileIndex = -1;
                        tempArr[i, j].hasCollision = false;
                        tempArr[i, j].collisionType = COLLISION_TYPE.NONE;
                        tempArr[i, j].hasEvent = false;
                        tempArr[i, j].collisionEvent = null;
                        tempArr[i, j].hasObject = false;
                        tempArr[i, j].objectType = OBJECT_TYPE.NONE;
                        tempArr[i, j].objectName = null;
                        tempArr[i, j].pairedTileX = -1;
                        tempArr[i, j].pairedTileY = -1;
                    }
                }
                if (oldMapHeight < mapHeight)
                {
                    for (int i = 0; i < mapWidth; ++i)
                    {
                        for (int j = 0; j < oldMapHeight; ++j)
                        {
                            tempArr[i, j].tileIndex = currentLayer.map[i, j].tileIndex;
                            tempArr[i, j].hasCollision = currentLayer.map[i, j].hasCollision;
                            tempArr[i, j].collisionType = currentLayer.map[i, j].collisionType;
                            tempArr[i, j].hasEvent = currentLayer.map[i, j].hasEvent;
                            tempArr[i, j].collisionEvent = currentLayer.map[i, j].collisionEvent;
                            tempArr[i, j].hasObject = currentLayer.map[i, j].hasObject;
                            tempArr[i, j].objectType = currentLayer.map[i, j].objectType;
                            tempArr[i, j].objectName = currentLayer.map[i, j].objectName;
                            tempArr[i, j].pairedTileX = currentLayer.map[i, j].pairedTileX;
                            tempArr[i, j].pairedTileY = currentLayer.map[i, j].pairedTileY;


                        }
                    }
                }
                else
                {
                    for (int i = 0; i < mapWidth; ++i)
                    {
                        for (int j = 0; j < mapHeight; ++j)
                        {
                            tempArr[i, j].tileIndex = currentLayer.map[i, j].tileIndex;
                            tempArr[i, j].hasCollision = currentLayer.map[i, j].hasCollision;
                            tempArr[i, j].collisionType = currentLayer.map[i, j].collisionType;
                            tempArr[i, j].hasEvent = currentLayer.map[i, j].hasEvent;
                            tempArr[i, j].collisionEvent = currentLayer.map[i, j].collisionEvent;
                            tempArr[i, j].hasObject = currentLayer.map[i, j].hasObject;
                            tempArr[i, j].objectType = currentLayer.map[i, j].objectType;
                            tempArr[i, j].objectName = currentLayer.map[i, j].objectName;
                            tempArr[i, j].pairedTileX = currentLayer.map[i, j].pairedTileX;
                            tempArr[i, j].pairedTileY = currentLayer.map[i, j].pairedTileY;


                        }
                    }
                }
                currentLayer.map = tempArr;
                layerList.Remove(layerList[layer]);
                layerList.Insert(layer, currentLayer);
                currentLayer = layerList[layer];
            }
        }
        private void tileWidthUpDown_ValueChanged(object sender, EventArgs e)
        {
            tileSetWidth = tm.GetTextureWidth(imageID) / (int)tileWidthUpDown.Value;
            

            tileSetGrid = new bool[tileSetWidth, tileSetHeight];
            for (int i = 0; i < tileSetWidth; ++i)
            {
                for (int j = 0; j < tileSetHeight; ++j)
                {
                    tileSetGrid[i, j] = false;
                }
            }

            hMapScroll.Maximum = mapWidth * (int)tileWidthUpDown.Value;
        }

        private void tileHeightUpDown_ValueChanged(object sender, EventArgs e)
        {
            tileSetHeight = tm.GetTextureHeight(imageID) / (int)tileHeightUpDown.Value;

            tileSetGrid = new bool[tileSetWidth, tileSetHeight];
            for (int i = 0; i < tileSetWidth; ++i)
            {
                for (int j = 0; j < tileSetHeight; ++j)
                {
                    tileSetGrid[i, j] = false;
                }
            }
            vMapScroll.Maximum = mapHeight * (int)tileHeightUpDown.Value;
        }

        //TOOL STRIP
        //New Map
        //Load Tileset
        //Save Map
        //Load Map
        //Exit
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            mapWidthUpDown.Value = 15;
            mapHeightUpDown.Value = 14;
            tileWidthUpDown.Value = 32;
            tileHeightUpDown.Value = 32;

            indexToPairX = -1;
            indexToPairY = -1;

            mapWidth = (int)mapWidthUpDown.Value;
            mapHeight = (int)mapHeightUpDown.Value;
            tileSetWidth = tm.GetTextureWidth(imageID) / (int)tileWidthUpDown.Value;
            tileSetHeight = tm.GetTextureHeight(imageID) / (int)tileHeightUpDown.Value;

            layerList = new List<Layer>(3);

            for (int i = 0; i < 3; ++i)
            {
                Layer tempLayer = new Layer();
                switch (i)
                {
                    case 0:
                        tempLayer.layerName = "Main Layer";
                        break;
                    case 1:
                        tempLayer.layerName = "Hidden Layer";
                        break;
                    case 2:
                        tempLayer.layerName = "Inverse Layer";
                        break;
                }
                tempLayer.map = new Tile[mapWidth, mapHeight];
                for (int j = 0; j < mapWidth; ++j)
                    for (int k = 0; k < mapHeight; ++k)
                    {
                        tempLayer.map[j, k].tileIndex = -1;
                        tempLayer.map[j, k].collisionEvent = null;
                        tempLayer.map[j, k].collisionType = COLLISION_TYPE.NONE;
                        tempLayer.map[j, k].objectName = null;
                        tempLayer.map[j, k].objectType = OBJECT_TYPE.NONE;
                        tempLayer.map[j, k].hasCollision = false;
                        tempLayer.map[j, k].hasObject = false;
                        tempLayer.map[j, k].hasEvent = false;
                        tempLayer.map[j, k].pairedTileX = -1;
                        tempLayer.map[j, k].pairedTileY = - 1;
                    }
                tempLayer.visible = true;

                layerList.Insert(i, tempLayer);
                listBox1.Items.Add(layerList[i].layerName);
            }
            listBox1.SelectedItem = listBox1.Items[0];
            currentLayer = layerList[0];

            tileSetGrid = new bool[tileSetWidth, tileSetHeight];
            for (int i = 0; i < tileSetWidth; ++i)
            {
                for (int j = 0; j < tileSetHeight; ++j)
                {
                    tileSetGrid[i, j] = false;
                }
            }

            solidCollisionRadio.Select();
            enemySpawnRadio.Select();
            stickGuardRadio.Select();
            swordStickGuardRadio.Select();
            tilesCheckBox.Checked = true;
            collisionCheckBox.Checked = true;
            objectsCheckBox.Checked = true;
            showTiles = true;
            showObjects = true;
            showCollision = true;
        }
        private void tilesetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (filepath != null)
            {
                OpenFileDialog dlg = new OpenFileDialog();

                if (DialogResult.OK == dlg.ShowDialog())
                {
                    filename = dlg.SafeFileName;
                    imageID = tm.LoadTexture(filepath + "//" + filename, 0);
                }
            }
            else
            {
                MessageBox.Show("Please select a filepath (File->Set Filepath).");
            }
        }
        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "Bin Files|*.bin";
            dlg.DefaultExt = "bin";
            dlg.FilterIndex = 0;

            if (DialogResult.OK == dlg.ShowDialog())
            {
                BinaryWriter bW = new BinaryWriter(dlg.OpenFile(), Encoding.ASCII);

                bW.Write(filename.Length);
                bW.Write(filename.ToCharArray());

                bW.Write(mapWidth);
                bW.Write(mapHeight);
                bW.Write((int)tileWidthUpDown.Value);
                bW.Write((int)tileHeightUpDown.Value);
                bW.Write(tileSetWidth);
                bW.Write(tileSetHeight);                

                for (int layer = 0; layer < 3; ++layer)
                {
                    bW.Write(layerList[layer].layerName.Length);
                    bW.Write(layerList[layer].layerName.ToCharArray());
                    for (int i = 0; i < layerList[layer].map.GetLength(0); ++i)
                    {
                        for (int j = 0; j < layerList[layer].map.GetLength(1); ++j)
                        {
                            bW.Write(layerList[layer].map[i, j].tileIndex);
                            bW.Write(layerList[layer].map[i, j].hasCollision);
                            if (layerList[layer].map[i, j].hasCollision)
                            {
                                bW.Write((int)layerList[layer].map[i, j].collisionType);
                                bW.Write(layerList[layer].map[i, j].hasEvent);
                                if (layerList[layer].map[i, j].hasEvent)
                                {
                                    bW.Write(layerList[layer].map[i, j].collisionEvent.Length);
                                    bW.Write(layerList[layer].map[i, j].collisionEvent.ToCharArray());
                                }
                            }
                            bW.Write(layerList[layer].map[i, j].hasObject);
                            if (layerList[layer].map[i, j].hasObject)
                            {
                                bW.Write((int)layerList[layer].map[i, j].objectType);
                                bW.Write(layerList[layer].map[i, j].objectName.Length);
                                bW.Write(layerList[layer].map[i, j].objectName.ToCharArray());
                            }                                
                            bW.Write(layerList[layer].map[i, j].pairedTileX);
                            bW.Write(layerList[layer].map[i, j].pairedTileY);
                        }
                    }
                }
                bW.Close();
            }
        }
        private void mapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (filepath == null)
            {
                MessageBox.Show("Please select a filepath (File->Set Filepath).");
            }
            else
            {
                OpenFileDialog dlg = new OpenFileDialog();
                dlg.Filter = "Bin Files|*.bin";
                dlg.DefaultExt = "bin";
                dlg.FilterIndex = 0;


                if (DialogResult.OK == dlg.ShowDialog())
                {
                    layerList.Clear();
                    BinaryReader bR = new BinaryReader(dlg.OpenFile(), Encoding.ASCII);
                    int textLength;

                    solidCollisionRadio.Select();
                    enemySpawnRadio.Select();
                    stickGuardRadio.Select();
                    swordStickGuardRadio.Select();
                    tilesCheckBox.Checked = true;
                    collisionCheckBox.Checked = true;
                    objectsCheckBox.Checked = true;
                    showTiles = true;
                    showObjects = true;
                    showCollision = true;

                    textLength = bR.ReadInt32();
                    filename = new string(bR.ReadChars(textLength));

                    imageID = tm.LoadTexture(filepath + "//" + filename, 0);

                    mapWidth = bR.ReadInt32();
                    mapHeight = bR.ReadInt32();
                    tileWidthUpDown.Value = bR.ReadInt32();
                    tileHeightUpDown.Value = bR.ReadInt32();
                    tileSetWidth = bR.ReadInt32();
                    tileSetHeight = bR.ReadInt32();

                    for (int layer = 0; layer < 3; ++layer)
                    {
                        Layer tempLayer = new Layer();
                        tempLayer.map = new Tile[mapWidth, mapHeight];

                        textLength = bR.ReadInt32();
                        tempLayer.layerName = new string(bR.ReadChars(textLength));

                        for (int i = 0; i < tempLayer.map.GetLength(0); ++i)
                        {
                            for (int j = 0; j < tempLayer.map.GetLength(1); ++j)
                            {
                                tempLayer.map[i, j].tileIndex = bR.ReadInt32();
                                tempLayer.map[i, j].hasCollision = bR.ReadBoolean();

                                if (tempLayer.map[i, j].hasCollision)
                                {
                                    tempLayer.map[i, j].collisionType = (COLLISION_TYPE)bR.ReadInt32();
                                    tempLayer.map[i, j].hasEvent = bR.ReadBoolean();
                                    if (tempLayer.map[i, j].hasEvent)
                                    {
                                        textLength = bR.ReadInt32();
                                        tempLayer.map[i, j].collisionEvent = new string(bR.ReadChars(textLength));
                                    }
                                    else
                                        tempLayer.map[i, j].collisionEvent = null;
                                }
                                else
                                {
                                    tempLayer.map[i, j].collisionType = COLLISION_TYPE.NONE;
                                    tempLayer.map[i, j].collisionEvent = null;
                                }
                                tempLayer.map[i, j].hasObject = bR.ReadBoolean();
                                if (tempLayer.map[i, j].hasObject)
                                {
                                    tempLayer.map[i, j].objectType = (OBJECT_TYPE)bR.ReadInt32();
                                    textLength = bR.ReadInt32();
                                    tempLayer.map[i, j].objectName = new string(bR.ReadChars(textLength));
                                }
                                else
                                {
                                    tempLayer.map[i, j].objectType = OBJECT_TYPE.NONE;
                                    tempLayer.map[i, j].objectName = null;
                                }
                                tempLayer.map[i, j].pairedTileX = bR.ReadInt32();
                                tempLayer.map[i, j].pairedTileY = bR.ReadInt32();
                            }
                        }
                        tempLayer.visible = true;

                        //layerList.Remove(layerList[layer]);
                        layerList.Insert(layer, tempLayer);
                        listBox1.Items.Add(layerList[layer].layerName);
                    }
                    listBox1.SelectedItem = listBox1.Items[0];
                    currentLayer = layerList[0];

                    mapWidthUpDown.Value = mapWidth;
                    mapHeightUpDown.Value = mapHeight;

                    tileSetGrid = new bool[tileSetWidth, tileSetHeight];
                    for (int i = 0; i < tileSetWidth; ++i)
                    {
                        for (int j = 0; j < tileSetHeight; ++j)
                        {
                            tileSetGrid[i, j] = false;
                        }
                    }
                    bR.Close();
                }
                
            }
            
        }
        private void setFilepathToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                filepath = dlg.SelectedPath;
            }
        }

        //LIST BOX
        //Change Index
        //Show/Hide Layer
        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {        
            if (listBox1.SelectedItem.ToString() == "Main Layer")
                currentLayer = layerList[0];
            else if (listBox1.SelectedItem.ToString() == "Hidden Layer")
                currentLayer = layerList[1];
            else if (listBox1.SelectedItem.ToString() == "Inverse Layer")
                currentLayer = layerList[2];
        }
        private void showHideButton_Click(object sender, EventArgs e)
        {
            currentLayer.visible = !currentLayer.visible;
            for (int i = 0; i < 3; ++i)
            {
                if (currentLayer.layerName.ToString() == layerList[i].layerName.ToString())
                {
                    layerList.Remove(layerList[i]);
                    layerList.Insert(i, currentLayer);
                    currentLayer = layerList[i];
                }
            }
        }
    }
}